package uoc.ei.practica;

import uoc.ei.tads.Iterador;

/** 
 * Definición del TAD de gestión del campeonato de apalabrados
 */
public interface ScrabbleManager {
	
	public static int MAX_LETTERS=29;
	public static int MAX_CARDS_USER = 7;
	public static int MAX_CARDS_GAME = 100;
	public static int MAX_CELLS = 15;
	
	public static char ORIENTATION_H='H';
	public static char ORIENTATION_V='V';
	
			
	/**
	 * celda del tablero vacía
	 */
	public final static int XX = 0;

	/**
	 * celda especial doble letra (DL)
	 */
	public final static int DL = 1;

	/**
	 * celda especial triple letra (TL)
	 */
	public final static int TL = 2;
	
	/**
	 * celda especial doble palabra (DP)
	 */
	public final static int DP = 3;
	
	/**
	 * celda especial triple palabra (TP)
	 */
	public final static int TP = 4;
	
	/**
	 * tablero de la partida. Utilizad estos datos para rellenar 
	 * el tablero. 
	 */
	public final static int[][] board = {
			{XX,XX,TP,XX,TL,XX,XX,XX,XX,XX,TL,XX,TP,XX,XX},
			{XX,TL,XX,XX,XX,DP,XX,XX,XX,DP,XX,XX,XX,TL,XX},
			{TP,XX,DL,XX,XX,XX,TL,XX,TL,XX,XX,XX,DL,XX,TP},
			{XX,XX,XX,TL,XX,XX,XX,DL,XX,XX,XX,TL,XX,XX,XX},
			{TL,XX,XX,XX,XX,XX,DL,XX,DL,XX,XX,XX,XX,XX,TL},
			{XX,DP,XX,XX,XX,TL,XX,XX,XX,TL,XX,XX,XX,DP,XX},
			{XX,XX,TL,XX,DL,XX,XX,XX,XX,XX,DL,XX,TL,XX,XX},
			{XX,XX,XX,DP,XX,XX,XX,XX,XX,XX,XX,DP,XX,XX,XX},
			{XX,XX,TL,XX,DL,XX,XX,XX,XX,XX,DL,XX,TL,XX,XX},
			{XX,DP,XX,XX,XX,TL,XX,XX,XX,TL,XX,XX,XX,DP,XX},
			{TL,XX,XX,XX,XX,XX,DL,XX,DL,XX,XX,XX,XX,XX,TL},
			{XX,XX,XX,TL,XX,XX,XX,DP,XX,XX,XX,TL,XX,XX,XX},
			{TP,XX,DL,XX,XX,XX,TL,XX,TL,XX,XX,XX,DL,XX,TP},
			{XX,TL,XX,XX,XX,DP,XX,XX,XX,DP,XX,XX,XX,TL,XX},
			{XX,XX,TP,XX,TL,XX,XX,XX,XX,XX,TL,XX,TP,XX,XX}
	};

	
	
	/**
	 * método que crea un nuevo campeonato con un nombre que lo identifica
	 * unívocamente.
	 * @param name nombre del campeonato a crear
	 * @throws EIException se lanza una excepción en el caso que el nombre
	 * del campeonato ya exista.
	 */
	public void addChampionShip(String championShipId) throws EIException;

	/**
	 * método que proporciona un iterador con los campeonatos del sistema.
	 * @return retorna el iterador
	 * @throws EIException lanza una excepción en el caso que no exista ningún 
	 * campeonato
	 */
	public Iterador<ChampionShip> championShips() throws EIException;
	
	/**
	 * método que añade una palabra en el sistema para un campeonato.
	 * En el caso que el campeonato no exista se deberá lanzar una excepción.
	 * En el caso que la palabra exista se lanzará una excepción. En cualquier caso,
	 * no existirán palabras repetidas en el sistema.
	 * @param word la palabra a añadir
	 * @param chanpionShipId identificador del campeonato
	 * @throws EIException la excepción a lanzar.
	 */
	public void addWord(String championShipId, String word) throws EIException;
	
	
	/**
	 * método que proporciona un iterador de todas las palabras del 
	 * diccionario de un campeonato
	 * @return iterador con las palabras
	 * @throws EIException lanza una excepción en el caso que no exista palabras 
	 * o el campeonato no exista
	 */
	public Iterador<Word> words(String championShipId) throws EIException;
	

	/**
	 * método que añade una letra con una puntuación en un campeonato
	 * y genera un número (total) de fichas para una partida 
	 * @param championShipId identificador del campionato
	 * @param letter la letra
	 * @param points el número de puntos
	 * @param total número de fichas a generar
	 * @throws EIException lanza una excepción en el caso que la letra supere el máximo establecido
	 * o que se añadan más letras que las estimadas (MAX_LETTERS).
	 */
	public void addLetter(String championShipId, String letter, int points, int total) throws EIException;
	
	/**
	 * método que retorna un iterador de las letras que existen en un campeonato
	 * @param championShipId identificador del campeonato
	 * @return iterador con las letras
	 * @throws EIException la excepción a lanzar 
	 */
	public Iterador<Letter> letters(String championShipId) throws EIException;
	
	/**
	 * método que añade una partida sobre un campeonato.
	 * @param championShipId identificador del campeonato a añadir
	 * @param gameId identificador de la partida 
	 * @param player1 nombre del primer jugador
	 * @param player2 nombre del segundo jugador
	 * @throws EIException lanza una excepción en el caso que no exista
	 * el campionato o que ya exista una partida con este nombre
	 */
	public void addGame(String championShipId, String gameId, String player1, String player2) throws EIException;
	
	/**
	 * método que proporciona las partidas de un campeonato
	 * @param championShipId identificador del campeonato
	 * @return retorna les partides de un campeonato
	 * @throws EIException lanza una excepción en el caso 
	 * que no exista el campeonato o no existan partidas.
	 */
	public Iterador<Game> games(String championShipId) throws EIException;
	
	/**
	 * método que añade una ficha a una partida de un campeonato
	 * @param championShip identificador del campeonato
	 * @param gameId identificador de la partida
	 * @param letter letra a añadir
	 * @throws EIException lanza una excepción en el caso que el campeonato, 
	 * la partida o la letra no sean válidas; 
	 * o en el caso que la partida ya haya empezado. 
	 */
	public void addCard(String championShip, String gameId, String letter) throws EIException;

	/**
	 * método que inicializa una partida de un campeonato 
	 * y asigna a cada jugador sus fichas iniciales. 
	 * @param championShipId identificador del campeonato
	 * @param gameId identificador de la partida
	 * @throws EIException lanza una excepción en el caso que la 
	 * partida (y/o campeonato) no existan
	 */
	public void startGame(String championShipId, String gameId) throws EIException;
	
	/**
	 * método que proporciona las fichas que se han asignado en una partida a un jugador
	 * @param championShipId identificador del campeonato
	 * @param gameId identificador de la partida
	 * @param playerId identificador del jugador
	 * @return retorna la lista de fichas de un jugador
	 * @throws EIException lanza una excepción en el caso que
	 * un campeonato, partida o jugador no exista o no existan fichas.
	 */
	public Iterador<Card> cards(String championShipId, String gameId, String playerId) throws EIException;
	

	/**
	 * método que proporcina las fichas que se han asignado a una partida
	 * @param championShipId identificador del campeonato
	 * @param gameId identificador de la partida
	 * @return retorna la lista de fichas de una partida
	 * @throws EIException lanza una excepción en el caso 
	 * que un campeonato o partida no exista o no hayan fichas.
	 */
	public Iterador<Card> cardsGame(String championShipId, String gameId) throws EIException;
	
	/**
	 * método que finaliza una partida. Fuerza el final de la partida
	 * aunque los jugadores y/o la partida aún tengan fichas. Esta es una simplificación respecto a la
	 * especificación definida en las PECs.
	 * @param championShipId identificador del campeonato
	 * @param gameId identificador de la partida
	 * @throws EIException lanza una excepción en el caso que el campeonato o la partida no existan. 
	 */
	public void finishGame(String championShipId, String gameId) throws EIException;
	
	
	/**
	 * método que proporciona la clasificación de un campeonato.
	 * @param championShipId identificador del campeonato
	 * @return retorna un iterador con los jugadores ordenados según las puntuaciones 
	 * de las diferentes partidas.
	 * @throws EIException lanza una excepción en el caso que no exista el campeonato.
	 */
	public Iterador<Player> classification(String championShipId) throws EIException;
	
	/**
	 * método que añade un nuevo jugador en el sistema.
	 * @param nif identificador del jugador
	 * @param nom nombre del jugador
	 * @throws EIException 
	 */
	public void addPlayer(String nif, String name) throws EIException;
	
	
	/**
	 * método que proporciona información de un jugador del sistema
	 * @param nif identificador del jugador
	 * @return retorna el jugador
	 * @throws EIException lanza una excepción en el caso que el jugador no exista.
	 */
	public Player getPlayer(String nif) throws EIException;
	
	/**
	 * método que proporciona los jugadores del sistema.
	 * @return iterador con los jugadores 
	 * @throws EIException lanza una excepción en el caso que no existan jugadores
	 */
	public Iterador<Player> players() throws EIException;
	
	
	/**
	 * método que añade o elimina una inscripción de un jugador a un campeonata
	 * @param championShipId identificador del campeonato
	 * @param nif identificador del jugador
	 * @throws EIException lanza una excepción en caso que el campeonato o jugador no exista.
	 */
	public void addOrRemoveInscription(String championShipId, String nif) throws EIException;
	
	
	/**
	 * método que proporciona los jugadores inscritos en un campeonato. 
	 * @param championShipId identificador de un campeonato
	 * @return retorna un iterador de los jugadores inscritos en un campeonato
	 * @throws EIException lanza una excepción en el caso que no haya jugadores inscritos en un campeonato
	 */
	public Iterador<Player> inscriptions(String championShipId) throws EIException;
	

	/**
	 * método que cierra una inscripción para un campeonato
	 * @param championShipId identificador del campeonato
	 * @throws EIException lanza una excepción en el caso que el campeonato no exista
	 */
	public void closeInscription(String championShipId) throws EIException;
	
	/**
	 * método que realiza una jugada de un jugador en el campeonato. En esta implementación para 
	 * simplificar se han tomado las siguientes decisiones: 
	 * - la implementación de la PRA NO tratará palabras cruzadas. Sólo se comptabilitazán la 
	 *   palabra actual. 
	 * - No hay ninguna restricción para ubicar la primera jugada en una posición determinada. 
	 * - No se valida el orden alternativo para jugar. Se supone como precondición que este orden ya es el correcto.
	 * - No se valida que se sobreescriban palabras o casillas.
	 *  
	 * @param championShipId identificador del campeonato
	 * @param gameId identificador de la partida
	 * @param playerId jugador que realiza la jugada
	 * @param row fila
	 * @param column columna
	 * @param orientation orientación
	 * @param word palabra
	 * @return retorna la puntuación de esta jugada
	 * @throws EIException lanza una excepción en el caso que el campeonato, partida o jugador no exista; o la partida no esté iniciada
	 */
	public int play(String championShipId, String gameId, String playerId, int row, int column, char orientation, String word) throws EIException;
		 
	
	/**
	 * método que proporciona el tablero de una partida
	 * @param championShipId identificador del campeonato
	 * @param gameID identificador de la partida.
	 * @return retorna el tablero de la partida
	 * @throws EIException lanza una excepción en el cas que el campeonato o la partida no existan
	 */
	public Board showBoard(String championShipId, String gameID) throws EIException;

	public Player findPlayer(String nif);

	public Player findPlayerRegistered(String championShipId, String nif);

	public ChampionShip findChampionShip(String championShipId);

	void changeCard(String championShipId, String gameId, String playerId,
			char charCard) throws EIException;

	
}
